{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " Affine et attaque fréquentielle\n", "
\n", "

Navigation dans la page

\n", "

\n", " Si c'est votre première visite dans ce TP, lisez attentivement chacun des points détaillé après ce paragraphe.
\n", " Si vous avez déjà commencer à travailler sur ce TP et que vous souhaiter vous déplacer rapidement dans une partie précise vous pouvez choisir la partie que vous souhaitez rejoindre ci-dessous.
\n", "

\n", " Menu de navigation\n", " \n", "
\n", "

\n", "\n", "
\n", " Technologie jupyter\n", "

\n", " La technologie jupyter permet d'exécuter du code python par un simple clique sur Executer ci-dessus.
\n", " Les morceaux de code de cette page sont interprétées case par case. Pour savoir quelle case a été interprétée avant une autre, il suffit de repérer le numéro devant la case.
\n", " Une fois qu'une case a été interprétée (=exécutée), la page garde en mémoire les variables et fonctions lues
\n", " La plateforme propose quelques outils de purge de la mémoire : \n", "

\n", "

\n", "
\n", "

SAUVEGARDER VOTRE TRAVAIL

\n", "

\n", " Pour ne pas perdre votre travail pensez à le sauvegarder régulièrement. Par défault, la sauvegarde par un clic sur la disquette en haut à gauche de page, ou par le racourci clavier classique ctrl+S\n", " est une sauvegarde en local, sur le serveur de jupyter. Vous pouvez et devez très régulièrement sauvegarder votre travail sur votre support personnel de sauvegarde (clef USB, se l'envoyer par mail etc). Ce faisant vous disposerez d'un fichier .ipynb (IPYthon NoteBook) qu'il vous suffira de recharger pour avancer. Après le rechargement assurez vous que les fonctionnalités anciennement developpées et variables utilisées sont bien dans la mémoire de la page (en rééxecutant les cases, ou plus rapidement par Kernel > Restart & Run All.

\n", "

A NOTER : vous pouvez travailler sur le tp (et tout autre fichier .ipynb) hors connexion en installant une version local du notebook de jupyter. Il faut que votre machine possède un interpreteur de python et que vous soyez connecter à internet.\n", "

    \n", "
  1. Lancer un terminal
  2. \n", "
  3. Taper la commande suivante : pip install jupyterlab
  4. \n", "
  5. Une fois l'installation terminée portez votre attention sur les dernières lignes affichées dans votre terminal vous invitant probablement à taper une ligne de commande pour faire une mise à jour
  6. \n", "
  7. Pour lancer notebook de jupyter, taper dans votre termial : jupyter notebook
  8. \n", "
  9. Votre simulateur de serveur est lancé. Il ne faut pas fermer votre terminal, auquel cas votre simulateur de serveur s'interompera. Suivez le lien indiqué dans les dernières lignes de votre terminal pour vous diriger vers votre espace local. L'interface se présente comme celle que vous trouverez sur le web. Votre travail sera cependant toujours enregistré et jamais perdu même si vous le consultez après plusieurs jours
  10. \n", "
\n", "

\n", "
\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Comme pour le TP1, ne bibliothèque regroupant quelques outils de la cryptologie vous ont été donnée. Chargeons l'intégralité des fonctionnalités qu'elle propose

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from OutilsCrypto import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Vous êtes invité à travailler sur la première partie du TP1 pour vous refamiliariser avec les fonctionnalités de cette bibliothèque comme codex, codex, xedoc, paquet, mode2base, Filtre ainsi que les fonctions d'attaque par dictionnaire.

" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " Partie 1 : Outils arithmétiques\n", "
\n", "\n", "

\n", "

\n", " Menu de navigation\n", " \n", "
\n", "

" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Ecrire la fonction PGCD qui prend en paramètre deux entiers a et b et qui renvoie le plus grand diviseur commun à ces deux nombres.

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def PGCD(a, b) :\n", " return 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Tests

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a=10\n", "b=15\n", "print(\"PGCD(\",a,\", \",b,\")=\", PGCD(a, b))#5\n", "a=100\n", "b=150\n", "print(\"PGCD(\",a,\", \",b,\")=\", PGCD(a, b))#50\n", "a=1983\n", "b=666\n", "print(\"PGCD(\",a,\", \",b,\")=\", PGCD(a, b))#3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

En imitant le développement de l'algorithme vu en cours, écrire la fonction inv_mod qui prend en paramètre deux entiers a et n et renvoie l'inverse de a modulo n. On convient que lorsque c'est impossible, la fonciton renvoie $0$

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def inv_mod(a, n) :\n", " return 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Tests

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a=[19, 11, 876, 1777]\n", "n=[13, 4, 484, 1111]\n", "for i in range(len(a)) :\n", " a1=inv_mod(a[i], n[i])\n", " if(a1==0) : print(a[i], \"n'est pas inversible modulo\", n[i])\n", " else : print(a[i], \"^(-1) modulo\", n[i], \"=\", a1)\n", "#19 ^(-1) modulo 13 = 11\n", "#11 ^(-1) modulo 4 = 3\n", "#876 n'est pas inversible modulo 484\n", "#1777 ^(-1) modulo 1111 = 739" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " Partie 2 : Chiffrement affine\n", "
\n", "\n", "

\n", "

\n", " Menu de navigation\n", " \n", "
\n", "

" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Ecrire la fonction Eaffine(txt, a, b, paq=1) qui a trois paramètres obligatoires et un paramètre optionnel:\n", "

\n", "Cette fonction renvoie une chaine de caractère correspondant au chiffrement affine txt de clef (a, b) par paquet de paq. Si paq vaut 1 alors la fonction devra retourner le décodage des entiers calculer. Sinon la fonction renverra une chaine de caractère correspondant aux entiers chiffrés du message séparé par des $\\texttt{-}$.
\n", "Par exemple le message $\\texttt{BONJOUR}$ de clef $(7, 19)$ par paquet de 1 donne $\\texttt{ANGENDI}$ alors que par paquet de 2, la fonction renvoie $\\texttt{817-1604-2381-1815}$.
\n", "\n", "La fonction renvoie la chaine vide (ie $\\texttt{\"\"}$) en cas d'erreur.\n", "

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def Eaffine(txt, a, b, paq=1) :\n", " return \"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Tests

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "txt=\"BONJOUR\"\n", "clefa=7\n", "clefb=19\n", "print(\"Par paquet de 1 :\", Eaffine(txt, clefa, clefb))\n", "print(\"Par paquet de 2 :\", Eaffine(txt, clefa, clefb, 2))\n", "txt=\"Il était une fois...\"\n", "clefa=2019\n", "clefb=1983\n", "print(\"Par paquet de 2 :\", Eaffine(txt, clefa, clefb, 2))\n", "print(\"Par paquet de 2 :\", Eaffine(Filtre(txt), clefa, clefb, 2))\n", "clefa=2017\n", "clefb=1983\n", "print(\"Par paquet de 2 :\", Eaffine(txt, clefa, clefb, 2))\n", "print(\"Par paquet de 2 :\", Eaffine(Filtre(txt), clefa, clefb, 2))\n", "#Par paquet de 1 : ANGENDI\n", "#Par paquet de 2 : 817-1604-2381-1815\n", "#Par paquet de 2 : \n", "#Par paquet de 2 : 18-1734-453-1053-141-1563-1521\n", "#Par paquet de 2 : \n", "#Par paquet de 2 : 922-896-437-2265-59-535-2411" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Ecrire la fonction Daffine(txt, a, b, paq=1) qui a trois paramètres obligatoires et un paramètre optionnel:\n", "

\n", "Cette fonction renvoie une chaine de caractère correspondant au déchiffrement affine txt de clef (a, b) par paquet de paq.
\n", "ATTENTION : si paq vaut 1 alors txt est une suite de lettre de l'alphabet. Sinon cette chaine est une suite d'entiers séparés par des $\\texttt{-}$. On pourra récupérer une liste de chaine de caractère des entiers par txt.split('-')
\n", "La fonction renvoie la chaine vide (ie $\\texttt{\"\"}$) en cas d'erreur.\n", "

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def Daffine(txt, a, b, paq=1) :\n", " return \"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Tests

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Test 1\n", "txt0=\"BONJOUR\"\n", "clefa=3\n", "clefb=9\n", "txt1=Eaffine(txt0, clefa, clefb)\n", "txt2=Daffine(txt1, clefa, clefb)\n", "print(txt0)\n", "print(txt1)\n", "print(txt2)#Doit redonner txt0\n", "\n", "#Test 1\n", "txt=\"La vie n'est pas un long fleuve tranquille !\"\n", "txt0=Filtre(txt)\n", "clefa=2017\n", "clefb=2021\n", "txt1=Eaffine(txt0, clefa, clefb, 3)\n", "txt2=Daffine(txt1, clefa, clefb, 3)\n", "print(txt)\n", "print(txt0)\n", "print(txt1)\n", "print(txt2)#Doit redonner txt0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " Partie 3 : Retour sur la brute force avec dictionnaire\n", "
\n", "

\n", "

\n", " Menu de navigation\n", " \n", "
\n", "

" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Comme nos l'avons vu avec le chiffrement de César, nous allons nous intérésser ici à une attaque en brute force avec dictionnaire. Exécuter le code suivant pour charger les différents dictionnaires proposée. ATTENTION : Cette opération peux prendre plusieurs secondes (environ 30). Un message de fin s'affichera lorsque le chargement sera terminé.

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(\"-----> DéBUT DU CHARGMENT DES DICTIONNAIRES <-----\")\n", "top=time.time()\n", "lang=\"FR\"\n", "print(\"CHARGEMENT DU DICTIONNAIRE \\\"\", lang, \"\\\": \\tEN COURS\",end='')\n", "DICO_FR = MonDico(lang)\n", "print(\"\\rCHARGEMENT DU DICTIONNAIRE \\\"\", lang, \"\\\": \\tTERMINéE (en\", round(time.time()-top, 3), \"secondes)\")\n", "top=time.time()\n", "lang=\"ANG\"\n", "print(\"CHARGEMENT DU DICTIONNAIRE \\\"\", lang, \"\\\": \\tEN COURS\",end='')\n", "DICO_ANG = MonDico(lang)\n", "print(\"\\rCHARGEMENT DU DICTIONNAIRE \\\"\", lang, \"\\\": \\tTERMINéE (en\", round(time.time()-top, 3), \"secondes)\")\n", "top=time.time()\n", "lang=\"ESP\"\n", "print(\"CHARGEMENT DU DICTIONNAIRE \\\"\", lang, \"\\\": \\tEN COURS\",end='')\n", "DICO_ESP = MonDico(lang)\n", "print(\"\\rCHARGEMENT DU DICTIONNAIRE \\\"\", lang, \"\\\": \\tTERMINéE (en\", round(time.time()-top, 3), \"secondes)\")\n", "top=time.time()\n", "lang=\"IT\"\n", "print(\"CHARGEMENT DU DICTIONNAIRE \\\"\", lang, \"\\\": \\tEN COURS\",end='')\n", "DICO_IT = MonDico(lang)\n", "print(\"\\rCHARGEMENT DU DICTIONNAIRE \\\"\", lang, \"\\\": \\tTERMINéE (en\", round(time.time()-top, 3), \"secondes)\")\n", "print(\"-----> FIN DU CHARGMENT DES DICTIONNAIRES <-----\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Ecrire une procédure BruteForcAffine_dico qui prend en paramètre : \n", "

\n", "Cette procédure réalise une attaque en brute forcemais n'affiche que des chaines décryptées de plus en plus pertinente.\n", "

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def BruteForceAffine_dico(txt, paq=1, dico=DICO_FR) : \n", " try : \n", " txt=str(txt)\n", " paq=int(paq)\n", " except :\n", " print(\"L'attaque ne fonctionne pas\")\n", " return\n", " \n", " print(\"\\t-----------------------------\")\n", " print(\"\\tBRUTE FORCE AVEC DICTIONNAIRE\")\n", " print(\"\\t-----------------------------\\n\")\n", "\n", " top=time.time()\n", " \n", " #Mettre votre code ici\n", " \n", " temps=time.time()-top\n", " print(\"\\rLe dernier message semble être le bon\")\n", " print(\"Attaque terminée (\"+str(round(temps, 3))+\"s)\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Tests

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "txt0=Filtre(\"My name is David. I'd like to have student who work\")\n", "clefa=19\n", "clefb=25\n", "paq=1\n", "txt1=Eaffine(txt0, clefa, clefb, paq)\n", "print(\"Message claire :\", txt0)\n", "print(\"Message à attaquer :\", txt1)\n", "BruteForceAffine_dico(txt1, paq, DICO_ANG)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Exécuter le code suivant demandera un petit temps de calcul (environ 1 minute (sur un core i5))\n", "txt0=Filtre(\"Une poule sur un mur qui picore du pain dure... elle a rien de mieux à faire ? Nan mais sérieux là !\")\n", "clefa=2017\n", "clefb=1234\n", "paq=2\n", "txt1=Eaffine(txt0, clefa, clefb, paq)\n", "print(\"Message claire :\", txt0)\n", "print(\"Message à attaquer :\", txt1)\n", "BruteForceAffine_dico(txt1, paq, DICO_FR)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " Partie 4 : Attaque fréquentielle\n", "
\n", "

\n", "

\n", " Menu de navigation\n", " \n", "
\n", "

" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Ecrire une fonction lst_freq qui prend en paramètre un texte et renvoie un tableau (sous forme de dictionnaire) ou la case 'A' est la fréquence de la lettre A, la case 'B' celle de la lettre B etc...

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def lst_freq(txt) :\n", " return {'?':0}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Tests

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "txt=\"Voici un texte plutot court, comme mes blagues ^_^\"\n", "lettre=\"E\"\n", "print(txt, \"\\nLa fréquence de la lettre\", lettre, \"dans ce texte est\", round(100*(lst_freq(Filtre(txt).upper())[lettre]),2), \"%\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Ecrire la fonction lettre_plus_freq qui prend en paramètre un texte et renvoie le caractère le plus fréquent dans ce texte.

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def lettre_plus_freq(txt) :\n", " return \"E\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Tests

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "txt=\"Voici un texte plutot court, comme mes blagues ^_^\"\n", "print(txt, \"\\nLa lettre la plus fréquente dans ce texte est\", lettre_plus_freq((Filtre(txt).upper())))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Ecrire une fonction attaquefreqaffine_dico qui prend en paramètre :\n", "

\n", " Cette fonction affiche le résultat (et éventuellement les détails des opérations effectués) d'une attaque fréquentielle. \n", "

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def attaquefreqaffine_dico(txt, paq=1, dico=DICO_FR) : \n", " try : \n", " txt=str(txt)\n", " paq=int(paq)\n", " except :\n", " print(\"L'attaque ne fonctionne pas\")\n", " return\n", "\n", " if(paq>1) : \n", " print(\"Il n'est pas possible de faire une attaque fréquentielle s'il n'y a pas de caractère\")\n", " return \n", " \n", " print(\"\\t---------------------------------------\")\n", " print(\"\\tATTAQUE FREQUENTIELLE AVEC DICTIONNAIRE\")\n", " print(\"\\t---------------------------------------\\n\")\n", "\n", " top=time.time()\n", " \n", " #Mettre votre code ici\n", " \n", " temps=time.time()-top\n", " print(\"\\rLe dernier message semble être le bon\")\n", " print(\"Attaque terminée (\"+str(round(temps, 3))+\"s)\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Tests

" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Dans la case suivante, on réalise un test sur l'attaque fréquentielle mais aussi une comparaison de temps d'éxecution entre l'attaque en force brute et l'attaque fréquentielle. Normalement, une attaque fréquentielle est au moins 10 fois plus rapide qu'une brute force !

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "txt=\"Pour qu'une attaque fréquentielle soit pertinente, il faut que le message soit relativement long. Voici donc un texte plutôt long qui ne dis rien de franchement intéressant... un peu comme certain politicien. Oui ! Je suis engagé !!!\"\n", "clefa=17\n", "clefb=19\n", "txt0=Filtre(txt).upper()\n", "txt1=Eaffine(txt0, clefa, clefb)\n", "\n", "#Attaque en force brute\n", "BruteForceAffine_dico(txt1)\n", "\n", "#Attaque fréquentielle\n", "attaquefreqaffine_dico(txt1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " Partie 5 : Test\n", "
\n", "

\n", "

\n", " Menu de navigation\n", " \n", "
\n", "

" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Attaquer le message suivant qui a été chiffré par la méthode affine. Indiquer à votre enseignant l'auteur du texte claire pour obtenir un petit bonus (ou pas ^_^ )!

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "txt=\"SPATIYGGSNDAWYPSYZDSMSVNABAPHCPZUSARAWHYZCYGTCYVDAAZTCZYMSGSNWCYPZBNOYASXAZOSNYASXLIDSWAHCSPAHIOZNYPAISVDYABAPHCPZUSARAHIPPCYGHADCZZABNAGUSACGGISBYGISHCYPYDGATYZSPZCBIZAWAPZOIWWAHAUSADUSCSPTNCBBCPZHISOAWAPZTNCBBCPZDCBINZAHAWCOFCWVNACOCAGZUSADUSALYGYZASNCWSNWSNCYRACUSYTNCBBADCBINZAHAWCOFCWVNAOAPCAGZUSAOADCAZNYAPHABDSGCCFHYGZYPOZAWAPZRAWAGISLYAPGUSAOCZCYZHCPGDAMDCOYCDHOAWVNAAZOFCUSAZYGIPVNIHCYZGIPZISNDABDCPOFANHSNATDAZHAGIPCMIPYACNHAWWAPZRAHGYNCYGDAWCZYPAPLCYPWCZCYGRAATTINOHAZYNANHAWAGDYLNAGSPGSNGYGWCZNYGZAGGAWCZNYGZAGGABISNWCDPINABANHSABISNDCBNOYASGAAZNCQIPPCPZATYDDAUSADAGCPMAGPIWWAPZDPINACAZUSCYOYIPPAPIWWANCRCWCYGBDSGAZDAGIQASXZNYGZAAZLCMSAVNSYGGAWAPZHAGNYHACSXBISNBNGWABPZNCYZWANAWBDYGGCYZHAZANNASNGTCPZCGZYUSAGYPOIPPSAGBISNWIYRSGUSCOARISNGYVYAPUSCAPTYPBISNCBCYGANDAVCZZAWAPZHAWIPOCSNRAWAHNAGGCYNBZCPZCOCAGZUSADUSALYGYZASNUSYGIDDYOYZADCAPZNADCBINZAHAWCOFCWVNAUSADUSALYGYZASNCZZCNHGIDDYOYZCPZDCAPZNADCBINZAHAWCOFCWVNACOCAGZOADCWWAAZNYAPHABDSGCWIPWAAPOAWIWAPZGAGAPZYZBDSGTINZAPCFGYZCPZHIPOBCGBDSGDIPMZAWBGCWIPGYASNCHYGRACISWCHCWAAPLNYZRCYWBDINALIZNABCNHIPWCYGDATCYZAGZUSARAGIWWAYDDCYGAZLISGZAGLAPSTNCBBANGYHISOAWAPZGYTCYVDAWAPZLISGZAGLAPSZCBANDCBINZAHAWCOFCWVNAUSCBAYPAZCYGRAOANZCYPHALISGCLIYNAPZAPHSCAZCDINGRCISLNYGDCBINZAZISZAMNCPHACDAGZPVNAGAZNYAPHABDSGGONSZCPZBNITIPHWAPZOAGZPVNAGRAWAZYPGDIPMZAWBGBDAYPHCZIPPAWAPZHAONCYPZAHAHISZANLCPZHAGNLAGUSCCSOSPWINZADPCCRCWCYGIGNLANWCYGDAGYDAPOAPATSZBCGZNISVDAZDCYWWIVYDYZPAHIPPCCSOSPGYMPAAZDAGASDWIZBNITNTSZSPPIWOFSOFIZCDPINACCOCZCYZWIYUSYDAOFSOFIZCYGAZSPOFIGIPZISNWSNWSNCOAWIZCDPINACCBSNAWAPZOADCAZNYAPHABDSGNAPZNCPZHCPGWCOFCWVNAAZGAPZCPZAPWIYZISZAWIPWAYPOAPHYARCAPZAPHYGVYAPZZSPOISBSPBASBDSGTINZUSADABNAWYANCGNAWAPZCHYGRACGNAWAPZYDQCUSADUSAOFIGACSXRCDISGYAGHAWCTAPZNALIQIPGHIPOOAUSAOCAGZAZAXBDINIPGOAWQGZNADCYGGIPGWIPOCSNGAOCDWANSPYPGZCPZAZAXBDINIPGOAWQGZNACOCAGZDALAPZAZNYAPHABDSGCRABISGGCYCDINGDALIDAZAZCLAOSPZSWSDZSASXVCZZAWAPZHCCYDAGAPZNCSPWCRAGZSASXOINVACSHYMPAHAGCPOYAPGRISNGYDPATYZBCGDCWIYPHNANLNAPOAYDPAGCCNNZCBCGYDPCFGYZCBCGSPAWYPSZAWCYGCLAODCWYPAHCSPDINHISHCSPADCHQYDGABANOFCCSHAGGSGHADCBINZAHAWCOFCWVNAYDGABANOFCGSNSPVSGZAHABCDDCGRSGZACSHAGGSGHADCBINZAHAWCOFCWVNACYDGABANOFCGCYPGZCDDCAZNYAPHABDSGCDINGOAZIYGACSHCVPABCNDCMNCLYZHAGIPWCYPZYAPAZDCGLNYZHAGCBFQGYIPIWYAYPHSYGCPZWCZNYGZAYWCMYPCZYIPGISNYNACVYAPUSAZCZZACDSYHYGRACGIYZGCPGFSBBAAZGCPGOYWYANZSPCAGOANZAGBCGSPBIDZNIPDSMSVNAAZCPOYAPOINVACSLIQCMASNBCNZYHAGNYLCMAGHADCPSYZHYGWIYUSADAGZZIPPIWGAYMPASNYCDCSXNYLCMAGHADCPSYZBDSZIPYAPPACDAOINVACSHYZCRCWCYGBDSGCRATSGWANLAYDDUSAOAHYGMNCOYASXLIDCZYDAAPZAPHZGYTCOYDAWAPZDCBCNIDAVYAPUSAGCNBIPGAPCAZBCGSPVYAPMNCPHGAPGAZPAWATZBCGHCSPMNCPHGAOISNGOCNPISGHALIPGOIPLAPYNUSARCWCYGYDPATSZHIPPSPFIWWALYLCPZHALIYNSPIYGACSCSHAGGSGHADCBINZAHAGCOFCWVNASPIYGACSISSPAVZAGSNSPVSGZAGOSDBZCSHAGGSGHADCBINZAHAGCOFCWVNAGAPIWWCPZHCSPPIWZADUSARCWCYGBDSGWCYGDAOINVACSBANOFGIDYZCYNAWAPZGSNDAVSGZABDCOYHAPABNITNCUSAOAWIZSPYUSAOIWWAGYHCPGOAWIZSPYUSAYDNBCPHCYZZISZAGIPWAYDPABNIPIPCNYAPHABDSGYDPANAWSCBCGSPABDSWACRSGUSCOAUSARAWABNYGGAWSNWSNANTCYVDAWAPZCHCCSZNAGCWYGGAGIPZHRAPLIDGDIYPHAWIYLANGDAWCZYPDSYCSGGYYDWAUSYZZANCOIWWAWAGCPOYAPPAGAGBNCPOAGHRAPLIDAGCDCIYGACSHYZCDINGCRCWCYGBDSGCZNAGGCYDDCPZCSVNSYZHAOAZZANBIPGARAZACLAOZCPZHCBNIBIGCGCPGHISZACHYGRACOAUSCYDBNIPIPOAAGZZISZGIPVCMCMAHAGCLIYNUSCYDCBNYGOFAJUSADUSAWCZNAYPTINZSPUSADAWCDFASNYWBYZIQCVDACBISNGSYLYCNHAWWAPZGCPGNBYZRSGUSCOAUSAGAGOFCPGIPGPCASGGAPZBDSGUSCSPGASDNATNCYPRSGUSCOAUSADAHABNITSPHYGHAGIPAGBNCPOAAZBNYGOAWDCPOIDYUSANATNCYPRCWCYGRCWCYGBDSGWCYGDAOINVACSYPHSYGCPZAPOINAZISZAWCZNYGZAWAGISNYNARANISDCYZISZHAGSYZASPGYMAOISGGYPGAPTCOAHADCIYGACSAZHSVSGZAAZHADCBINZACDINGWCAPTIPCPZHCPGDALADISNGRAWCCBBDYUSCYAPOFCPANDAGYHAGCSXYHAGOFANOFCPZOAUSAOAZCSMSNCDIYGACSHAGCPOYAPGRISNGOAUSAOAZNYGZAHYGMNCOYASXGYPYGZNAWCYMNAAZCSMSNCDIYGACSHAGCPOYAPGRISNGLISDCYZTCYNAAPZAPHNAAPONICGGCPZGIPRCWCYGBDSGRAWAZAPCYGCYPGYNLCPZOIPRAOZSNCPZWCYGPCCHNAGGCPZBDSGSPAGQDDCVADCIYGACSHIPZDAGQASXCNHAPZGWAVNDCYAPZWCYPZAPCPZRSGUSCCSTIPHHSOCSNRAOFANOFCYGHALYPANOADCAZBDSGAPOINAWCZZANABIGCPZDCCYGAGSNDALADISNGHSOISGGYPUSAOCNAGGCYZDCDSWYNAHADCDCWBAOALADISNGLYIDAZOCNAGGBCNDCDSWYNAHADCDCWBAUSAGCZZAADDAPABNAGGANCBDSGCCFRCWCYGBDSGCDINGYDWAGAWVDCUSADCCYNGCBCYGGYGGCYZBCNTSWBCNSPAPOAPGIYNYPLYGYVDAUSAVCDCPCYAPZHAGGNCBFYPGHIPZDAGBCGTNDCYAPZDAZCBYGHADCOFCWVNACYPTINZSPCWCONYCYRACZIPHYASZCCHIPPBCNGAGCPMAGYDZCCAPLIQHSNBYZHSNBYZAZHSPBAPZFGHCPGZAGNAGGISLAPYNGHADPINAVIYGIFVIYGOAVIPPBAPZFGAZISVDYAOAZZADPINABANHSACDAOINVACSHYZCRCWCYGBDSGCCBNIBFZACHYGRACZNAHAWCDFASNIYGACSISHWIPWCYGZISRISNGBNIBFZAUSAZSGIYGSPAPLIQHSZAPZCZASNISUSADCZAWBZAZCCYZGYWBDAWAPZOFISPCSTNCMWCYGAPOINAYPZNBYHAGSNOAZZAZANNAHGANZAAPGINOADAHCPGOADIMYGBCNDCFINNASNFCPZCHYGWIYGYPONAWAPZRAZCAPGSBBDYAAXYGZAZYDAXYGZAZYDYOYSPVCSWAHARSHAHYGHYGRAZCAPGSBBDYACDAOINVACSHYZCRCWCYGBDSGCCBNIBFZACHYGRACZNAHAWCDFASNIYGACSISHWIPZISRISNGBNIBFZABCNOAOYADZAPHSGSNPIGZZAGBCNOAHYASUSAZISGHASXPISGCHINIPGHYGOAZZAWAOFCNMAHAHISDASNGYHCPGDABCNCHYGDIYPZCYPADDABISNNCAWVNCGGANSPATYDDAGCYPZAUSADAGCPMAGPIWWAPZDPINAAWVNCGGANSPABNOYASGAAZNCQIPPCPZATYDDAUSADAGCPMAGPIWWAPZDPINACDAOINVACSHYZCRCWCYGBDSGCCUSAOAZZABCNIDAGIYZDAGYMPCDHAPIZNAGBCNCZYIPIYGACSISHWIPCFSNDCYRAAPWANAHNAGGCPZCNAPZNAHCPGDCZAWBZANAZISNPACSNYLCMAHADCPSYZBDSZIPYAPPAPADCYGGABCGYOYSPAGASDABDSWAPIYNAOIWWAGISLAPYNHSWAPGIPMAUSAZIPWACBNITNDCYGGAWCGIDYZSHAYPLYIDAUSYZZAOAVSGZACSHAGGSGHAWCBINZACNNCOFAZIPVAOHAWIPOCSNAZBNOYBYZAZIPGBAOZNADIYPHAWCBINZACDAOINVACSHYZCRCWCYGBDSGCAZDAOINVACSYWWSCVDAAGZZISRISNGYPGZCDDZISRISNGYPGZCDDGSNDAVSGZABDAHABCDDCGRSGZACSHAGGSGHADCBINZAHAWCOFCWVNAAZGAGQASXIPZZISZADCGAWVDCPOAHAGQASXHCSPHWIPUSYNLAAZDCDSWYNAHADCDCWBAAPNSYGGADCPZGSNDSYBNIRAZZAGIPIWVNAGSNDABDCPOFANAZWIPWAFINGHSOANODAHAOAZZAIWVNAUSYMZTDIZZCPZAGSNDABDCPOFANPABISNNCBDSGGCDALANCRCWCYGBDSG\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " Bonus : Optimisation de l'attaque en brute force\n", "
\n", "

\n", "

\n", " Menu de navigation\n", " \n", "
\n", "

\n", "\n", "

On peut optimiser l'attaque en brute force.\n", "

\n", "\n", "

" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def BruteForceAffine_dico_2(txt, paq=1, dico=DICO_FR) : \n", " try : \n", " txt=str(txt)\n", " paq=int(paq)\n", " except :\n", " print(\"L'attaque ne fonctionne pas\")\n", " return\n", " print(\"\\t--------------------------------------\")\n", " print(\"\\tBRUTE FORCE AVEC DICTIONNAIRE OPTIMISé\")\n", " print(\"\\t--------------------------------------\\n\")\n", "\n", " top=time.time()\n", " \n", " #Mettre votre code ici\n", " \n", " temps=time.time()-top\n", " print(\"\\rLe dernier message semble être le bon\")\n", " print(\"Attaque terminée (\"+str(round(temps, 3))+\"s)\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Tests

" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "#le code suivant, qui avait couté environ une minute, ne devrait plus prendre que 5 secondes maintenant (sur un core i5).\n", "txt0=Filtre(\"Une poule sur un mur qui picore du pain dure... elle a rien de mieux à faire ? Nan mais sérieux là !\")\n", "clefa=2017\n", "clefb=1234\n", "paq=2\n", "txt1=Eaffine(txt0, clefa, clefb, paq)\n", "print(\"Message claire :\", txt0)\n", "print(\"Message à attaquer :\", txt1)\n", "BruteForceAffine_dico_2(txt1, paq, DICO_FR)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "txt=\"Je suis bien heureux d'arriver à la fin de ce TP ! L'inverse modulaire, je n'aime pas ca snif\"\n", "txt0=Filtre(txt)\n", "\n", "PAQ=[1, 2]\n", "for paq in PAQ : \n", " #Génération de clef\n", " print(\"-----------------------------------------------------------------------\")\n", " print(\" Par paquet de\", paq)\n", " print(\"-----------------------------------------------------------------------\")\n", " mod=mod2base(paq)\n", " a=random.randint(1, mod)\n", " while(PGCD(a, mod)>1) : a=random.randint(1, mod-1)\n", " b=random.randint(0, mod-1)\n", " txt1=Eaffine(txt0, a, b, paq)\n", " print(\"Message à attaquer :\", txt1)\n", " BruteForceAffine_dico(txt1, paq, DICO_FR)\n", " BruteForceAffine_dico_2(txt1, paq, DICO_FR)\n", " if(paq==1) : attaquefreqaffine_dico(txt1, paq, DICO_FR)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.0" } }, "nbformat": 4, "nbformat_minor": 2 }